package com.mk.ancientrpcstarter.server;

import com.mk.ancientrpcstarter.entity.RpcRequest;
import com.mk.ancientrpcstarter.entity.RpcResponse;
import com.mk.ancientrpcstarter.enums.CommandEnum;
import com.mk.ancientrpcstarter.logging.Log;
import com.mk.ancientrpcstarter.logging.LogFactory;
import com.mk.ancientrpcstarter.protocol.RpcProtocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.net.InetSocketAddress;

/**
 * @description:
 * @author: M.K
 * @date: 2021/12/18
 */

public class ServerHandler extends ChannelInboundHandlerAdapter {

    private Log log = LogFactory.getLog(ServerHandler.class);

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel ch = ctx.channel();
        InetSocketAddress socketAddress = (InetSocketAddress) ch.remoteAddress();
        String clientIp = socketAddress.getAddress().getHostAddress();

        log.debug("client connect to rpc server, client's ip is: " + clientIp);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel ch = ctx.channel();
        InetSocketAddress socketAddress = (InetSocketAddress) ch.remoteAddress();
        String clientIp = socketAddress.getAddress().getHostAddress();

        log.debug("client close the connection to rpc server, client's ip is: " + clientIp);
    }

    /**
     * 读事件, 业务逻辑处理 (这里应该是线程池处理)
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        byte[] recvData = (byte[]) msg;
        if (recvData.length == 0) {
            log.warn("receive request from client, but the data length is 0");
            return;
        }
        log.debug("receive request from client, the data length is: " + recvData.length);
        //反序列化请求数据
        RpcProtocol rpcReq = new RpcProtocol();
        rpcReq.byteArrayToRpcHeader(recvData);
        if(rpcReq.getMagicNum() != RpcProtocol.CONST_CMD_MAGIC){
            log.warn("request msgic code error");
            return;
        }
        //解析请求，并调用处理方法
        int ret = -1;
        if(rpcReq.getCmd() == CommandEnum.REQUEST.getCode()){
            RpcRequest request = rpcReq.byteArrayToRequest(rpcReq.getBody());
            // TODO 这里反射调用对应的handler方法
            // TODO 1. 通过uri获取对应的方法
            // TODO 2. 调用方法获取返回对象
            // TODO 3. 构造返回数据
            RpcResponse response = new RpcResponse();
            RpcProtocol rpcResp = new RpcProtocol();
            rpcResp.setCmd(rpcReq.getCmd());
            rpcResp.setVersion(rpcReq.getVersion());
            rpcResp.setMagicNum(rpcReq.getMagicNum());
            rpcResp.setBodyLen(Integer.BYTES);
            byte[] body = rpcResp.createUserRespTobyteArray(ret);
            rpcResp.setBody(body);
            ByteBuf respData = Unpooled.copiedBuffer(rpcResp.generateByteArray());
            ctx.channel().writeAndFlush(respData);
        }
    }
}
